﻿
namespace PhotoAlbum.Web.Services
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using PhotoAlbum.Web;

    [EnableClientAccess()]
    public class UserTaggingService : PhotoAlbumService
    {
        [Query(HasSideEffects = false)]
        public IQueryable<UserTag> GetUserTagsForPictureId(int pictureId)
        {
            var picture = this.GetViewablePicture(pictureId);
            return picture.UserTags.CreateSourceQuery().Include("User").OrderBy(t => t.User.UserName);
        }

        [RequiresAuthentication]
        [Query(HasSideEffects = false)]
        public IQueryable<UserTag> GetUserTags()
        {
            return this.PhotoUser.UserTags.CreateSourceQuery().OrderBy(t => t.Id);
        }

        [Query(HasSideEffects = false)]
        public IQueryable<UserTag> GetUserTagsForUserId(int userId)
        {
            if (this.PhotoUser != null
                && this.PhotoUser.Id == userId)
            {
                return GetUserTags();
            }
            var user = this.ObjectContext.PhotoAlbumUsers.FirstOrDefault(u => u.Id == userId);
            if (user == null)
            {
                throw new Exception("User cannot be found.");
            }
            return this.ObjectContext
                        .UserTags
                        .Where(ut => ut.UserId == userId
                            && ut.Picture.Album.VisibilityStore == (int)AlbumVisibility.Public)
                        .OrderBy(ut => ut.Id);

        }

        [RequiresAuthentication]
        [Query(HasSideEffects = true)]
        public IQueryable<UserTag> AddTagForUsernameToPictureId([Required] string username, int pictureId)
        {
            return this.AddTagForUsernameAndPositionToPictureId(username, pictureId, 0, 0);
        }

        [Query(HasSideEffects = true)]
        public IQueryable<UserTag> AddTagForUsernameAndPositionToPictureId([Required] string username, int pictureId, int x, int y)
        {
            var picture = this.GetViewablePicture(pictureId);
            var user = this.ObjectContext.PhotoAlbumUsers.FirstOrDefault(u => u.UserName == username);
            if (user != null)
            {
                var tag = new UserTag()
                {
                    AuthorId = this.PhotoUser.Id,
                    UserId = user.Id,
                    PictureId = pictureId,
                    Position = new Position() { X = x, Y = y }
                };
                picture.UserTags.Add(tag);
                this.ObjectContext.SaveChanges();
                return picture.UserTags.CreateSourceQuery();
            }
            return Enumerable.Empty<UserTag>().AsQueryable();
        }

        [RequiresAuthentication]
        public void DeleteUserTag(UserTag userTag)
        {
            if (userTag.AuthorId != this.PhotoUser.Id
                && userTag.UserId != this.PhotoUser.Id)
            {
                throw new Exception("Only the author and the target of a UserTag can remove it.");
            }

            if ((userTag.EntityState == EntityState.Detached))
            {
                this.ObjectContext.UserTags.Attach(userTag);
            }
            this.ObjectContext.UserTags.DeleteObject(userTag);
        }
    }
}


